#ifndef CRITTERB_H
#define CRITTERB_H

#include "src/filesystem/be_filesystem.h"
#include "btBulletDynamicsCommon.h"
// #include "GL/gl.h"

// #include "src/common/be_parser.h"
#include "src/brainz/brainz.h"
#include "src/utils/settings.h"
#include "src/utils/displaylists.h"
#include "genotypes.h"
#include "bodyowner.h"

using namespace std;

class CritterB : public Bodyowner
{
	public:
		CritterB(btDynamicsWorld* btWorld, long unsigned int id, const btVector3& startPos);
		CritterB(CritterB& , long unsigned int id, const btVector3& startPos, bool brainmutant, bool bodymutant);
		CritterB(string &critterstring, btDynamicsWorld* btWorld, const btVector3& startPos);
		~CritterB();

		Brainz			brain;
		Genotype*		genotype;
		inline void		registerBrainInputOutputs();
    unsigned int  getNumberOfInputs();
    unsigned int  getNumberOfOutputs();
    float     beEaten(float amount);
		void			draw();
		void			move();

		
		unsigned long		critterID;

// 		unsigned int		adamdist;
		btScalar		position[16];

// 		float			speciescolor[3];
// 		float			colorTrim;
		bool			loadError;

		float			energyUsed;
		unsigned int		totalFrames;

		// Inputs
		bool			canProcreate;
    bool      beingTouched;
    bool      beingEaten;

		// Motor Func
		bool			procreate;

		unsigned int		procreateTimeCount;
		unsigned int		procreateTimeTrigger;

    void preprocess(vector<CritterB*>& critters, vector<Entity*>& entities, unsigned long long frameCount);
    void process(vector<CritterB*>& critters, vector<Entity*>& entities, unsigned long long frameCount);
    void postprocess(vector<CritterB*>& critters, vector<Entity*>& entities, unsigned long long frameCount);

		// Vision
// 		unsigned int		components;
		float			straal;
		
		float			fitness_index;

		vector<unsigned int>	crittersWithinRange;
		
	private:

		Settings*		settings;
		Genotypes*		genotypes;

		unsigned int		movementsmade;

		btDynamicsWorld*	btDynWorld;

		inline void		initConst();
		inline void		procInputNeurons();
		inline void		procOutputNeurons();
		inline void		createInputOutputNeurons();

			const unsigned int*	critter_maxlifetime;
			const unsigned int*	critter_maxenergy;
			const unsigned int*	critter_sightrange;
			const unsigned int*	critter_procinterval;
			const unsigned int*	critter_minenergyproc;

			const unsigned int*	brain_costhavingneuron;
			const unsigned int*	brain_costfiringneuron;
			const unsigned int*	brain_costfiringmotorneuron;
			const unsigned int*	brain_costhavingsynapse;
			const unsigned int*	colormode;


};

#endif
